package org.tomale.id;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.tomale.id.common.KeyValuePair;
import org.tomale.id.ui.Activator;
import org.tomale.id.ui.preference.pages.PreferenceConstants;

/**
 * 
 * @author ferd
 *
 */
public class User {

	static User _instance;
	
	int _id;
	String _name;
	
	List<String> _permissions;
	
	IUserProvider _provider;
	
	private User(){
		_id = 0;
	}
	
	public static User getInstance(){
		if(_instance == null){
			_instance = new User();
		}
		return _instance;
	}
	
	public boolean isSignedIn(){
		return _id != 0;
	}
	
	public boolean isAllowed(final String permissionId){
		if(!isSignedIn()){
			signIn();
		}
		return _permissions.contains(permissionId);
	}
	
	public void signIn() throws SecurityException {
		Activator.getDefault().showSignInDialog();
	}
	
	public boolean signIn(final String username, final String password) throws SecurityException{
		try {
			boolean result = getProvider().authenticate(username, password);
			if(result){
				// cache permissions
				_permissions = getProvider().getPermissions(username);
			}
			return result;
		}catch(ProviderException e){
			throw new SecurityException("Unable to authenticate user.",e);
		}
	}
	
	public IUserProvider getProvider() throws ProviderException {
		if(_provider == null){
			IPreferenceStore store = Activator.getDefault().getPreferenceStore();
			String provider = store.getString(PreferenceConstants.USER_PID);
			
			IConfigurationElement[] elems = Platform.getExtensionRegistry().getConfigurationElementsFor(Activator.PLUGIN_ID);
			for(IConfigurationElement elem : elems){
				if(provider.equals(elem.getAttribute("class"))){
					try {
						Object o = elem.createExecutableExtension("class");
						if(o instanceof IUserProvider){
							_provider = (IUserProvider) o;
							break;
						}
					}catch(CoreException e){
						throw new ProviderException(MessageFormat.format("Unable to create an instance of provider '{0}'.", provider));
					}
				}
			}
		}
		return _provider;
	}
	
	public static List<KeyValuePair<String, String>> getProviders(){
		ArrayList<KeyValuePair<String, String>> providers = new ArrayList<KeyValuePair<String,String>>();
		IConfigurationElement[] elems = Platform.getExtensionRegistry().getConfigurationElementsFor(Activator.PLUGIN_ID);
		for(IConfigurationElement elem : elems){
			providers.add(new KeyValuePair<String, String>(elem.getAttribute("class"),	
					elem.getAttribute("description")));
		}
		return providers;
	}
}
